"""
订单管理器

负责订单的创建、跟踪和管理
"""

import os
import csv
import json
import time
from typing import Dict, List, Any, Optional
from datetime import datetime
from ..core import unified_logger
from ..core.exceptions import OrderError, ValidationError


class OrderManager:
    """订单管理器"""
    
    def __init__(self, storage_path: str = "./data"):
        """
        初始化订单管理器
        
        Args:
            storage_path: 数据存储路径
        """
        self.storage_path = storage_path
        self.orders_file = os.path.join(storage_path, "orders.csv")
        self.logger = unified_logger.get_logger('order_manager')
        
        # 创建存储目录
        os.makedirs(storage_path, exist_ok=True)
        
        # 初始化订单文件
        self._init_orders_file()
        
        # 内存中的订单缓存
        self._orders_cache: Dict[str, Dict[str, Any]] = {}
        
        # 加载现有订单
        self._load_orders()
    
    def _init_orders_file(self) -> None:
        """初始化订单CSV文件"""
        if not os.path.exists(self.orders_file):
            headers = [
                'order_id', 'exchange', 'symbol', 'type', 'side', 'amount', 
                'price', 'filled_amount', 'filled_price', 'status', 
                'create_time', 'update_time', 'strategy', 'leverage'
            ]
            
            with open(self.orders_file, 'w', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                writer.writerow(headers)
    
    def _load_orders(self) -> None:
        """从文件加载订单到内存缓存"""
        try:
            if not os.path.exists(self.orders_file):
                return
            
            with open(self.orders_file, 'r', encoding='utf-8') as f:
                reader = csv.DictReader(f)
                for row in reader:
                    order_id = row['order_id']
                    if order_id:
                        # 转换数值字段
                        row['amount'] = float(row['amount']) if row['amount'] else 0.0
                        row['price'] = float(row['price']) if row['price'] else 0.0
                        row['filled_amount'] = float(row['filled_amount']) if row['filled_amount'] else 0.0
                        row['filled_price'] = float(row['filled_price']) if row['filled_price'] else 0.0
                        row['create_time'] = int(row['create_time']) if row['create_time'] else 0
                        row['update_time'] = int(row['update_time']) if row['update_time'] else 0
                        row['leverage'] = int(row['leverage']) if row['leverage'] else 1
                        
                        self._orders_cache[order_id] = row
            
            self.logger.info(f"加载了 {len(self._orders_cache)} 个订单到缓存")
            
        except Exception as e:
            self.logger.error(f"加载订单失败: {e}")
    
    def _save_order_to_file(self, order: Dict[str, Any]) -> None:
        """保存订单到CSV文件"""
        try:
            # 检查文件是否存在，如果不存在则创建
            if not os.path.exists(self.orders_file):
                self._init_orders_file()
            
            # 追加订单到文件
            with open(self.orders_file, 'a', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                row = [
                    order.get('order_id', ''),
                    order.get('exchange', ''),
                    order.get('symbol', ''),
                    order.get('type', ''),
                    order.get('side', ''),
                    order.get('amount', 0),
                    order.get('price', 0),
                    order.get('filled_amount', 0),
                    order.get('filled_price', 0),
                    order.get('status', ''),
                    order.get('create_time', 0),
                    order.get('update_time', 0),
                    order.get('strategy', ''),
                    order.get('leverage', 1)
                ]
                writer.writerow(row)
                
        except Exception as e:
            self.logger.error(f"保存订单到文件失败: {e}")
    
    def _update_orders_file(self) -> None:
        """更新整个订单文件"""
        try:
            # 重写整个文件
            headers = [
                'order_id', 'exchange', 'symbol', 'type', 'side', 'amount', 
                'price', 'filled_amount', 'filled_price', 'status', 
                'create_time', 'update_time', 'strategy', 'leverage'
            ]
            
            with open(self.orders_file, 'w', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                writer.writerow(headers)
                
                for order in self._orders_cache.values():
                    row = [
                        order.get('order_id', ''),
                        order.get('exchange', ''),
                        order.get('symbol', ''),
                        order.get('type', ''),
                        order.get('side', ''),
                        order.get('amount', 0),
                        order.get('price', 0),
                        order.get('filled_amount', 0),
                        order.get('filled_price', 0),
                        order.get('status', ''),
                        order.get('create_time', 0),
                        order.get('update_time', 0),
                        order.get('strategy', ''),
                        order.get('leverage', 1)
                    ]
                    writer.writerow(row)
                    
        except Exception as e:
            self.logger.error(f"更新订单文件失败: {e}")
    
    def create_order(self, exchange: str, symbol: str, order_type: str, side: str,
                    amount: float, price: Optional[float] = None, 
                    strategy: str = '', leverage: int = 1) -> Dict[str, Any]:
        """
        创建新订单
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            order_type: 订单类型 (limit/market)
            side: 买卖方向 (buy/sell)
            amount: 数量
            price: 价格 (限价单必需)
            strategy: 策略名称
            leverage: 杠杆倍数
            
        Returns:
            订单信息
        """
        try:
            # 验证参数
            if not symbol or not order_type or not side:
                raise ValidationError("订单参数不能为空")
            
            if amount <= 0:
                raise ValidationError("订单数量必须大于0")
            
            if order_type == 'limit' and (price is None or price <= 0):
                raise ValidationError("限价单必须指定有效价格")
            
            # 生成订单ID
            order_id = self._generate_order_id()
            
            # 创建订单对象
            order = {
                'order_id': order_id,
                'exchange': exchange,
                'symbol': symbol,
                'type': order_type,
                'side': side,
                'amount': amount,
                'price': price or 0.0,
                'filled_amount': 0.0,
                'filled_price': 0.0,
                'status': 'created',
                'create_time': int(time.time()),
                'update_time': int(time.time()),
                'strategy': strategy,
                'leverage': leverage
            }
            
            # 保存到缓存和文件
            self._orders_cache[order_id] = order
            self._save_order_to_file(order)
            
            self.logger.order_log(order, 'CREATE')
            return order
            
        except Exception as e:
            self.logger.error(f"创建订单失败: {e}")
            raise OrderError(f"创建订单失败: {e}")
    
    def _generate_order_id(self) -> str:
        """生成唯一的订单ID"""
        timestamp = int(time.time() * 1000)  # 毫秒时间戳
        return f"XC{timestamp}"
    
    def update_order_status(self, order_id: str, status: str, 
                           filled_amount: Optional[float] = None,
                           filled_price: Optional[float] = None) -> bool:
        """
        更新订单状态
        
        Args:
            order_id: 订单ID
            status: 新状态
            filled_amount: 成交数量
            filled_price: 成交价格
            
        Returns:
            是否更新成功
        """
        try:
            if order_id not in self._orders_cache:
                raise OrderError(f"订单不存在: {order_id}")
            
            order = self._orders_cache[order_id]
            old_status = order['status']
            
            # 更新订单信息
            order['status'] = status
            order['update_time'] = int(time.time())
            
            if filled_amount is not None:
                order['filled_amount'] = filled_amount
            
            if filled_price is not None:
                order['filled_price'] = filled_price
            
            # 更新文件
            self._update_orders_file()
            
            self.logger.order_log(order, f'UPDATE_{status.upper()}')
            self.logger.info(f"订单状态更新: {order_id} {old_status} -> {status}")
            
            return True
            
        except Exception as e:
            self.logger.error(f"更新订单状态失败: {e}")
            return False
    
    def get_order(self, order_id: str) -> Optional[Dict[str, Any]]:
        """
        获取订单信息
        
        Args:
            order_id: 订单ID
            
        Returns:
            订单信息，如果不存在返回None
        """
        return self._orders_cache.get(order_id)
    
    def get_orders_by_status(self, status: str) -> List[Dict[str, Any]]:
        """
        根据状态获取订单列表
        
        Args:
            status: 订单状态
            
        Returns:
            订单列表
        """
        return [order for order in self._orders_cache.values() 
                if order['status'] == status]
    
    def get_orders_by_symbol(self, symbol: str) -> List[Dict[str, Any]]:
        """
        根据交易对获取订单列表
        
        Args:
            symbol: 交易对
            
        Returns:
            订单列表
        """
        return [order for order in self._orders_cache.values() 
                if order['symbol'] == symbol]
    
    def get_orders_by_strategy(self, strategy: str) -> List[Dict[str, Any]]:
        """
        根据策略获取订单列表
        
        Args:
            strategy: 策略名称
            
        Returns:
            订单列表
        """
        return [order for order in self._orders_cache.values() 
                if order['strategy'] == strategy]
    
    def get_active_orders(self) -> List[Dict[str, Any]]:
        """
        获取活跃订单（未完成的订单）
        
        Returns:
            活跃订单列表
        """
        active_statuses = ['created', 'submitted', 'partial_filled']
        return [order for order in self._orders_cache.values() 
                if order['status'] in active_statuses]
    
    def get_recent_orders(self, limit: int = 100) -> List[Dict[str, Any]]:
        """
        获取最近的订单
        
        Args:
            limit: 返回数量限制
            
        Returns:
            最近订单列表
        """
        orders = list(self._orders_cache.values())
        orders.sort(key=lambda x: x['create_time'], reverse=True)
        return orders[:limit]
    
    def cancel_order(self, order_id: str) -> bool:
        """
        取消订单
        
        Args:
            order_id: 订单ID
            
        Returns:
            是否取消成功
        """
        try:
            if order_id not in self._orders_cache:
                raise OrderError(f"订单不存在: {order_id}")
            
            order = self._orders_cache[order_id]
            
            # 检查订单状态
            if order['status'] in ['filled', 'cancelled', 'rejected']:
                raise OrderError(f"订单状态不允许取消: {order['status']}")
            
            # 更新状态为已取消
            return self.update_order_status(order_id, 'cancelled')
            
        except Exception as e:
            self.logger.error(f"取消订单失败: {e}")
            return False
    
    def get_order_statistics(self) -> Dict[str, Any]:
        """
        获取订单统计信息
        
        Returns:
            统计信息
        """
        try:
            total_orders = len(self._orders_cache)
            
            if total_orders == 0:
                return {
                    'total_orders': 0,
                    'status_counts': {},
                    'exchange_counts': {},
                    'symbol_counts': {},
                    'strategy_counts': {}
                }
            
            # 按状态统计
            status_counts = {}
            exchange_counts = {}
            symbol_counts = {}
            strategy_counts = {}
            
            for order in self._orders_cache.values():
                # 状态统计
                status = order['status']
                status_counts[status] = status_counts.get(status, 0) + 1
                
                # 交易所统计
                exchange = order['exchange']
                exchange_counts[exchange] = exchange_counts.get(exchange, 0) + 1
                
                # 交易对统计
                symbol = order['symbol']
                symbol_counts[symbol] = symbol_counts.get(symbol, 0) + 1
                
                # 策略统计
                strategy = order['strategy']
                if strategy:
                    strategy_counts[strategy] = strategy_counts.get(strategy, 0) + 1
            
            return {
                'total_orders': total_orders,
                'status_counts': status_counts,
                'exchange_counts': exchange_counts,
                'symbol_counts': symbol_counts,
                'strategy_counts': strategy_counts
            }
            
        except Exception as e:
            self.logger.error(f"获取订单统计失败: {e}")
            return {}
    
    def cleanup_old_orders(self, days: int = 30) -> int:
        """
        清理旧订单
        
        Args:
            days: 保留天数
            
        Returns:
            清理的订单数量
        """
        try:
            cutoff_time = int(time.time()) - (days * 24 * 3600)
            
            orders_to_remove = []
            for order_id, order in self._orders_cache.items():
                if order['create_time'] < cutoff_time and order['status'] in ['filled', 'cancelled', 'rejected']:
                    orders_to_remove.append(order_id)
            
            # 从缓存中移除
            for order_id in orders_to_remove:
                del self._orders_cache[order_id]
            
            # 更新文件
            if orders_to_remove:
                self._update_orders_file()
            
            self.logger.info(f"清理了 {len(orders_to_remove)} 个旧订单")
            return len(orders_to_remove)
            
        except Exception as e:
            self.logger.error(f"清理旧订单失败: {e}")
            return 0